use actix_web::{App, HttpResponse, HttpServer, web};
use serde::Deserialize;

#[derive(Deserialize)]
struct GcdParameters {
    n: u64,
    m: u64,
}
#[actix_web::main]
async fn main() -> std::io::Result<()>{
    let server = HttpServer::new(
        //闭包表达式
        || {
            App::new()
                .route("/", web::get().to(get_index))
                .route("/gcd", web::post().to(post_gcd))
        },
    );
    println!("Serving on http://localhost:3000...");
    server
        .bind("127.0.0.1:3000")
        .expect("error binding server to address")
        .run().await
    //.expect("error running server");
}
async fn get_index() -> HttpResponse {
    HttpResponse::Ok().content_type("text/html").body(
        r#"
 <title>GCD Calculator</title>
 <form action="/gcd" method="post">
 <input type="text" name="n"/>
 <input type="text" name="m"/>
 <button type="submit">Compute GCD</button>
 </form>
 "#,
    )
}

async fn post_gcd(form: web::Form<GcdParameters>) -> HttpResponse {
    if form.n == 0 || form.m == 0 {
        return HttpResponse::BadRequest()
            .content_type("text/html")
            .body("Computing the GCD with zero is boring.");
    }
    let response = format!(
        "The greatest common divisor of the numbers {} and
{} \
 is <b>{}</b>\n",
        form.n,
        form.m,
        gcd(form.n, form.m)
    );
    HttpResponse::Ok().content_type("text/html").body(response)
}

fn gcd(n: u64, m: u64) -> u64 {
    if m == 0 && n == 0 {
        0
    } else {
        if m == 0 { n } else { gcd(m, n % m) }
    }
}
